EXTRACCIÓN DE DATOS GEOGRÁFICOS Y TEMPORALES¶

Notebook dedicado a la extracción de los metadatos geograficos y temporales. En el caso de los datos geográficos se enriquecerán aportando adicionalmente (distancia de residencia habitual, municipio y provincia)

0. Importación de packages y constantes¶

In [9]:
import pickle
import math
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px

# Packages propios
from utils.graphdbmanipulation import ImagesGraphDB
from utils.imagesmanipulation import ImageHelper
In [10]:
# Rutas de interés
PATH_IMAGENES_A_ANALIZAR = "c:/Users/dcsj/OneDrive/Formación/Masters & Postgrados/En Curso/UOC-Master en Ciencia de Datos/TFM/Imagenes/Movil-S21"
PATH_GML_FILE = 'c:/Users/dcsj/Repositorios/UOC_TFM/image_classifier/outputs/graphs/graph_GEO_TIME.gml'
# Coordenadas de residencia habitual
RESIDENCE_LATITUDE = 41.462435251362294
RESIDENCE_LONGITUDE = 2.203910532194043

1. Extracción y enriquecimiento de datos¶

Se van a extraer los datos del gps (latitud y longitud) de las imágenes en caso de que dispongan de esa información y la fecha de realización de la foto. A partir de la información de latitud y longitud, mediante el servicio https://nominatim.openstreetmap.org/reverse se van a obtener diversos datos adicionales:

  • city: municipio más cercano donde se tomó la foto
  • postcode: código postal
  • state_district: se corresponde con la provincia
  • state: se corresponde con la comunidad autonoma en el caso de España
  • country: pais

Además, con los datos de longitud y latitud extraidos se calculará la distancia en km respecto de la que es considerada residencia habitual. Por último, se realizará la extracción de la fecha y hora, día, mes y año como información necesaria para estudios de frecuencias y periodos que puedan ayudar en la determinación de álbumes.

In [4]:
# Se crea el objeto con la clase que habilita la extracción y enriquecimiento de datos
imagehelper = ImageHelper()
geo_date_data = imagehelper.get_geo_and_date_images_data(PATH_IMAGENES_A_ANALIZAR,RESIDENCE_LATITUDE,RESIDENCE_LONGITUDE)
geo_date_data.head(10)
Out[4]:
filename latitude longitude city postcode state_district state country distance_km datestring day month year
0 20210724_100218.jpg 41.458438 2.204826 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.450968 2021:07:24 10:02:18 24 7 2021
1 20210724_104730.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:31 24 7 2021
2 20210724_104736.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:36 24 7 2021
3 20210724_104739.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:39 24 7 2021
4 20210724_104743.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:44 24 7 2021
5 20210724_104757.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:57 24 7 2021
6 20210724_200143.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:43 24 7 2021
7 20210724_200145.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:45 24 7 2021
8 20210724_200231_02.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
9 20210724_200231_03.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
In [5]:
# Se guarda en un fichero csv el dataframe generado
geo_date_data.to_csv('.\outputs\csv\geo_date_data.csv')
In [11]:
# Se incorpora la información en un grafo y se guarda en un fichero gml
geo_date_data = pd.read_csv('.\outputs\csv\geo_date_data.csv',header=0)
imagesGraphDB = ImagesGraphDB()
for row in geo_date_data.itertuples():
    #nodo imagen
    node = str(row.filename)
    imagesGraphDB.add_node(row.filename)
    imagesGraphDB.set_attribute_to_node(row.filename,'type','image_filename')
    if row.city!='unknown':
        # Se añaden los atributos geográficos al nodo de imagen
        imagesGraphDB.set_attribute_to_node(row.filename,'distance_km',str(row.distance_km))
        imagesGraphDB.set_attribute_to_node(row.filename,'latitude',row.latitude)
        imagesGraphDB.set_attribute_to_node(row.filename,'longitude',row.longitude)
        # nodo municipio
        imagesGraphDB.add_node(row.city)
        imagesGraphDB.set_attribute_to_node(row.city,'type','municipio')
        imagesGraphDB.add_edge(row.filename,row.city)
        #nodo provincia
        imagesGraphDB.add_node(row.state_district)
        imagesGraphDB.add_edge(row.filename,row.state_district)
        imagesGraphDB.set_attribute_to_node(row.city,'type','provincia')
        imagesGraphDB.add_edge(row.city,row.state_district)
        #nodo país
        imagesGraphDB.add_node(row.country)
        imagesGraphDB.add_edge(row.filename,row.country)
        imagesGraphDB.set_attribute_to_node(row.country,'type','país')
        imagesGraphDB.add_edge(row.state_district,row.country)
        #nodo código postal
        imagesGraphDB.add_node(row.postcode)
        imagesGraphDB.add_edge(row.filename,row.postcode)
        imagesGraphDB.set_attribute_to_node(row.postcode,'type','código postal')
        #nodo dia
        imagesGraphDB.add_node(row.day)
        imagesGraphDB.add_edge(row.filename,row.day)
        imagesGraphDB.set_attribute_to_node(row.day,'type','día')
        #nodo mes
        imagesGraphDB.add_node(row.month)
        imagesGraphDB.add_edge(row.filename,row.month)
        imagesGraphDB.set_attribute_to_node(row.month,'type','mes')
        #nodo mes
        imagesGraphDB.add_node(row.month)
        imagesGraphDB.add_edge(row.filename,row.month)
        imagesGraphDB.set_attribute_to_node(row.month,'type','mes')
        #nodo año
        imagesGraphDB.add_node(row.year)
        imagesGraphDB.add_edge(row.filename,row.year)
        imagesGraphDB.set_attribute_to_node(row.month,'type','año')
imagesGraphDB.write_gml_file(PATH_GML_FILE)

2. Análisis de resultados¶

In [12]:
# Carga de resultados desde fichero csv
geo_date_data = pd.read_csv('.\outputs\csv\geo_date_data.csv',header=0)
geo_date_data.head(10)
Out[12]:
Unnamed: 0 filename latitude longitude city postcode state_district state country distance_km datestring day month year
0 0 20210724_100218.jpg 41.458438 2.204826 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.450968 2021:07:24 10:02:18 24 7 2021
1 1 20210724_104730.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:31 24 7 2021
2 2 20210724_104736.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:36 24 7 2021
3 3 20210724_104739.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:39 24 7 2021
4 4 20210724_104743.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:44 24 7 2021
5 5 20210724_104757.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:57 24 7 2021
6 6 20210724_200143.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:43 24 7 2021
7 7 20210724_200145.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:45 24 7 2021
8 8 20210724_200231_02.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
9 9 20210724_200231_03.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
In [14]:
# Filtrado de resultados para obtener solo los registros con datos de longitud y latitud
images_with_location = geo_date_data.loc[geo_date_data['latitude']>0]
images_with_location.head(10)
Out[14]:
Unnamed: 0 filename latitude longitude city postcode state_district state country distance_km datestring day month year
0 0 20210724_100218.jpg 41.458438 2.204826 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.450968 2021:07:24 10:02:18 24 7 2021
1 1 20210724_104730.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:31 24 7 2021
2 2 20210724_104736.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:36 24 7 2021
3 3 20210724_104739.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:39 24 7 2021
4 4 20210724_104743.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:44 24 7 2021
5 5 20210724_104757.jpg 41.455110 2.202973 Santa Coloma de Gramenet 08924 Barcelona Catalunya España 0.818283 2021:07:24 10:47:57 24 7 2021
6 6 20210724_200143.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:43 24 7 2021
7 7 20210724_200145.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230864 2021:07:24 20:01:45 24 7 2021
8 8 20210724_200231_02.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
9 9 20210724_200231_03.jpg 41.451868 2.208307 Santa Coloma de Gramenet 08921 Barcelona Catalunya España 1.230859 2021:07:24 20:02:31 24 7 2021
In [24]:
# Se trunca el valor de latitud y longitud a un decimal para hacer mapa de calor
truncate_factor = 10
images_with_location_truncated = geo_date_data.loc[geo_date_data['latitude']>0].copy()
images_with_location_truncated['latitude_truncated'] = images_with_location['latitude'].apply(lambda x: math.trunc(x*truncate_factor)/truncate_factor)
images_with_location_truncated['longitude_truncated'] = images_with_location['longitude'].apply(lambda x: math.trunc(x*truncate_factor)/truncate_factor)
images_with_location_truncated.head(10)
In [36]:
# Se agrupan por latitud y longitud para hacer un mapa de calor
df_grouped_area = images_with_location_truncated.groupby(['latitude_truncated','longitude_truncated']).size().reset_index(name='counts')
df_grouped_area.head(10)
Out[36]:
latitude_truncated longitude_truncated counts
0 40.7 0.2 55
1 40.8 0.1 175
2 40.8 0.2 24
3 40.8 0.8 7
4 41.1 1.5 64
5 41.1 1.6 6
6 41.3 2.0 4
7 41.3 2.1 99
8 41.4 2.1 6
9 41.4 2.2 133
In [42]:
# Se muestran los datos usando un mapbox
fig = px.density_mapbox(df_grouped_area, lat='latitude_truncated', lon='longitude_truncated', z='counts',
                        mapbox_style="stamen-terrain")
fig
In [16]:
# Se agrupa por día
df_grouped_date = geo_date_data.groupby(['year','month','day']).size().reset_index(name='counts')
df_grouped_date['date'] = df_grouped_date.apply(lambda x: str(x.year) +'_'+ str(x.month) +'_'+ str(x.day),axis=1)
df_grouped_date.sort_values(by='counts', ascending=False).head(10)
Out[16]:
year month day counts
0 2018 5 5 3
1 2018 8 22 1
2 2018 8 24 1
3 2021 7 24 17
4 2021 7 25 33
5 2021 7 31 85
6 2021 8 2 1
7 2021 8 6 4
8 2021 8 7 7
9 2021 8 13 1
In [34]:
# Se realiza un histograma del 2021
df_grouped_date_2021 = df_grouped_date.loc[df_grouped_date['year']==2021]
fig, ax = plt.subplots(figsize=(20,5))
fig.suptitle('Number of images per day (2021)')
ax.bar(df_grouped_date_2021['date'],df_grouped_date_2021['counts'])
plt.xticks(rotation=30, ha='right')
plt.show()

Se observa como la frecuencia de fotografias aumenta de forma muy significativa en periodos de vacaciones y en fechas que coinciden con eventos como cenas, comidas y/o cumpleaños.